/**
 Image editable input.
 **/
(function ($) {
    "use strict";

    var Image = function (options) {
        this.init('image', options, Image.defaults);

        if ('on_error' in options.image) {
            this.on_error = options.image['on_error'];
            delete options.image['on_error']
        }
        if ('on_success' in options.image) {
            this.on_success = options.image['on_success'];
            delete options.image['on_success']
        }
        if ('max_size' in options.image) {
            this.max_size = options.image['max_size'];
            delete options.image['max_size']
        }

        this.initImage(options, Image.defaults);
    };

    //inherit from Abstract input
    $.fn.editableutils.inherit(Image, $.fn.editabletypes.abstractinput);

    $.extend(Image.prototype, {
        initImage: function (options, defaults) {
            this.options.image = $.extend({}, defaults.image, options.image);
            this.name = this.options.image.name || 'editable-image-input';
        },

        /**
         Renders input from tpl

         @method render()
         **/
        render: function () {
            var self = this;
            this.$input = this.$tpl.find('input[type=hidden]:eq(0)');
            this.$file = this.$tpl.find('input[type=file]:eq(0)');

            this.$file.attr({'name': this.name});
            this.$input.attr({'name': this.name + '-hidden'});


            this.options.image.allowExt = this.options.image.allowExt || ['jpg', 'jpeg', 'png', 'gif'];
            this.options.image.allowMime = this.options.image.allowMime || ['image/jpg', 'image/jpeg', 'image/png', 'image/gif'];
            this.options.image.maxSize = self.max_size || this.options.image.maxSize || false;

            this.options.image.before_remove = this.options.image.before_remove || function () {
                    self.$input.val(null);
                    return true;
                }

            this.$file.ace_file_input(this.options.image).on('change', function () {
                var $rand = (self.$file.val() || self.$file.data('ace_input_files')) ? Math.random() + "" + (new Date()).getTime() : null;
                self.$input.val($rand)//set a random value, so that selected file is uploaded each time, even if it's the same file, because inline editable plugin does not update if the value is not changed!
            }).closest('.ace-file-input').css({'width': '150px'}).closest('.editable-input').addClass('editable-image');

            this.$file
                .off('file.error.ace')
                .on('file.error.ace', function (e, info) {
                    if (!self.on_error) return;
                    if (info.error_count['ext'] > 0 || info.error_count['mime'] > 0) {
                        //wrong ext or mime?
                        self.on_error(1);
                    }
                    else if (info.error_count['size'] > 0) {
                        //wrong size
                        self.on_error(2);
                    }
                });
        }

    });


    Image.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
        tpl: '<span><input type="hidden" /></span><span><input type="file" /></span>',
        inputclass: '',
        image: {
            style: 'well',
            btn_choose: 'Change Image',
            btn_change: null,
            no_icon: 'fa fa-picture-o',
            thumbnail: 'large'
        }
    });

    $.fn.editabletypes.image = Image;

}(window.jQuery));


//Wysiwyg
(function ($) {
    "use strict";

    var Wysiwyg = function (options) {
        this.init('wysiwyg', options, Wysiwyg.defaults);

        //extend wysiwyg manually as $.extend not recursive 
        this.options.wysiwyg = $.extend({}, Wysiwyg.defaults.wysiwyg, options.wysiwyg);
    };

    $.fn.editableutils.inherit(Wysiwyg, $.fn.editabletypes.abstractinput);

    $.extend(Wysiwyg.prototype, {
        render: function () {
            this.$editor = this.$input.nextAll('.wysiwyg-editor:eq(0)');

            this.$tpl.parent().find('.wysiwyg-editor').show().ace_wysiwyg(
                {
                    toolbar: [
                        'bold',
                        'italic',
                        'strikethrough',
                        'underline',
                        null,
                        'foreColor',
                        null,
                        'insertImage'
                    ]
                }
            )
                .prev().addClass('wysiwyg-style2')
                .closest('.editable-input').addClass('editable-wysiwyg')
                .closest('.editable-container').css({'display': 'block'});//if display is inline-block, putting large images inside the editor will expand it out of bounding box!

            if (this.options.wysiwyg && this.options.wysiwyg.css)
                this.$tpl.closest('.editable-wysiwyg').css(this.options.wysiwyg.css);
        },


        value2html: function (value, element) {
            $(element).html(value);
            return false;
        },

        html2value: function (html) {
            return html;
        },

        value2input: function (value) {
            this.$editor.html(value);
        },
        input2value: function () {
            return this.$editor.html();
        },

        activate: function () {
            //this.$editor.focus().get(0).setSelectionRange(200,200);
        }
    });


    Wysiwyg.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
        tpl: '<input type="hidden" /><div class="wysiwyg-editor"></div>',
        inputclass: 'editable-wysiwyg',
        wysiwyg: {}
    });

    $.fn.editabletypes.wysiwyg = Wysiwyg;

}(window.jQuery));


/**
 Spinner editable input.
 **/
(function ($) {
    "use strict";

    var Spinner = function (options) {
        this.init('spinner', options, Spinner.defaults);
        this.initSpinner(options, Spinner.defaults);

        this.nativeUI = false;
        try {
            var tmp_inp = document.createElement('INPUT');
            tmp_inp.type = 'number';
            this.nativeUI = tmp_inp.type === 'number' && this.options.spinner.nativeUI === true
        } catch (e) {
        }
    };

    //inherit from Abstract input
    $.fn.editableutils.inherit(Spinner, $.fn.editabletypes.abstractinput);

    $.extend(Spinner.prototype, {
        initSpinner: function (options, defaults) {
            this.options.spinner = $.extend({}, defaults.spinner, options.spinner);
        },

        /**
         Renders input from tpl

         @method render()
         **/
        render: function () {
        },

        /**
         Activates input: sets focus on the first field.

         @method activate()
         **/
        activate: function () {
            if (this.$input.is(':visible')) {
                this.$input.focus();
                $.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);

                if (!this.nativeUI) {
                    var val = parseInt(this.$input.val());
                    var options = $.extend({value: val}, this.options.spinner);
                    this.$input.ace_spinner(options);
                }
                else {
                    this.$input.get(0).type = 'number';
                    var options = ['min', 'max', 'step']
                    for (var o = 0; o < options.length; o++) {
                        if (options[o] in this.options.spinner)
                            this.$input.attr(options[o], this.options.spinner[options[o]])
                    }
                }
            }
        },

        /**
         Attaches handler to submit form in case of 'showbuttons=false' mode

         @method autosubmit()
         **/
        autosubmit: function () {
            this.$input.keydown(function (e) {
                if (e.which === 13) {
                    $(this).closest('form').submit();
                }
            });
        }
    });

    Spinner.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
        tpl: '<input type="text" />',
        inputclass: '',
        spinner: {
            min: 0,
            max: 100,
            step: 1,
            icon_up: 'fa fa-plus',
            icon_down: 'fa fa-minus',
            btn_up_class: 'btn-success',
            btn_down_class: 'btn-danger'
        }
    });

    $.fn.editabletypes.spinner = Spinner;

}(window.jQuery));


/**
 Slider editable input.
 **/
(function ($) {
    "use strict";

    var Slider = function (options) {
        this.init('slider', options, Slider.defaults);
        this.initSlider(options, Slider.defaults);

        this.nativeUI = false;
        try {
            var tmp_inp = document.createElement('INPUT');
            tmp_inp.type = 'range';
            this.nativeUI = tmp_inp.type === 'range' && this.options.slider.nativeUI === true
        } catch (e) {
        }
    };

    //inherit from Abstract input
    $.fn.editableutils.inherit(Slider, $.fn.editabletypes.abstractinput);

    $.extend(Slider.prototype, {
        initSlider: function (options, defaults) {
            this.options.slider = $.extend({}, defaults.slider, options.slider);
        },

        /**
         Renders input from tpl

         @method render()
         **/
        render: function () {
        },
        /**
         Activates input: sets focus on the first field.

         @method activate()
         **/
        activate: function () {
            if (this.$input.is(':visible')) {
                this.$input.focus();
                $.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);

                if (!this.nativeUI) {
                    var self = this;
                    var val = parseInt(this.$input.val());
                    var width = this.options.slider.width || 200;
                    var options = $.extend(this.options.slider, {
                        value: val,
                        slide: function (event, ui) {
                            var val = parseInt(ui.value);
                            self.$input.val(val);

                            if (ui.handle.firstChild == null) {//no tooltips attached to it
                                $(ui.handle).prepend("<div class='tooltip top in' style='display:none; top:-38px; left:-5px;'><div class='tooltip-arrow'></div><div class='tooltip-inner'></div></div>");
                            }
                            $(ui.handle.firstChild).show().children().eq(1).text(val);
                        }
                    });
                    this.$input.parent().addClass('editable-slider').css('width', width + 'px').slider(options);
                }
                else {
                    this.$input.get(0).type = 'range';
                    var options = ['min', 'max', 'step']
                    for (var o = 0; o < options.length; o++) {
                        if (options[o] in this.options.slider) {
                            this.$input[0][options[o]] = this.options.slider[options[o]]
                        }
                    }
                    var width = this.options.slider.width || 200;
                    this.$input.parent().addClass('editable-slider').css('width', width + 'px');
                }

            }
        },

        value2html: function (value, element) {
        },

        /**
         Attaches handler to submit form in case of 'showbuttons=false' mode

         @method autosubmit()
         **/
        autosubmit: function () {
            this.$input.keydown(function (e) {
                if (e.which === 13) {
                    $(this).closest('form').submit();
                }
            });
        }
    });

    Slider.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
        tpl: '<input type="text" /><span class="inline ui-slider-green"><span class="slider-display"></span></span>',
        inputclass: '',
        slider: {
            min: 1,
            max: 100,
            step: 1,
            range: "min"
        }
    });

    $.fn.editabletypes.slider = Slider;

}(window.jQuery));


/**
 ADate editable input.
 **/
(function ($) {
    "use strict";


    var ADate = function (options) {
        this.init('adate', options, ADate.defaults);
        this.initDate(options, ADate.defaults);

        this.nativeUI = false;
        try {
            var tmp_inp = document.createElement('INPUT');
            tmp_inp.type = 'date';
            this.nativeUI = tmp_inp.type === 'date' && this.options.date.nativeUI === true
        } catch (e) {
        }
    };

    //inherit from Abstract input
    $.fn.editableutils.inherit(ADate, $.fn.editabletypes.abstractinput);

    $.extend(ADate.prototype, {
        initDate: function (options, defaults) {
            this.options.date = $.extend({}, defaults.date, options.date);
        },

        /**
         Renders input from tpl

         @method render()
         **/
        render: function () {
            this.$input = this.$tpl.find('input.date');
        },
        /**
         Activates input: sets focus on the first field.

         @method activate()
         **/
        activate: function () {
            if (this.$input.is(':visible')) {
                this.$input.focus();
            }

            if (!this.nativeUI) {
                var inp = this.$input;
                this.$input.datepicker(this.options.date)
                var picker = inp.data('datepicker');
                if (picker) {
                    inp.on('click', function () {
                        picker.show();
                    })
                        .siblings('.input-group-addon').on('click', function () {
                            picker.show();
                        })
                }
            }
            else {
                this.$input.get(0).type = 'date';
            }

        },

        /**
         Attaches handler to submit form in case of 'showbuttons=false' mode

         @method autosubmit()
         **/
        autosubmit: function () {
            this.$input.keydown(function (e) {
                if (e.which === 13) {
                    $(this).closest('form').submit();
                }
            });
        }
    });

    ADate.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
        tpl: '<div class="input-group input-group-compact"><input type="text" class="input-medium date" /><span class="input-group-addon"><i class="fa fa-calendar"></i></span></div>',
        date: {
            weekStart: 0,
            startView: 0,
            minViewMode: 0
        }
    });

    $.fn.editabletypes.adate = ADate;

}(window.jQuery));